﻿// Jinx AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using Jinx.Naming.Paths;

namespace Jinx.Naming
{
    public class PathResolver
    {
        private readonly NamingContext Context;

        public PathResolver(NamingContext Context)
        {
            this.Context = Context;
        }

        public object Resolve(string Path)
        {
            try
            {
                return Resolve(PathParser.Parse(Path));
            }
            catch (PathParser.ParseException e)
            {
                throw new CouldNotResolvePath(e);
            }
        }

        public object Resolve(Path Path)
        {
            try
            {
                object Cursor = null;

                foreach (var Node in Path)
                    Cursor = Node.Resolve(Context, Cursor);

                return Cursor;
            }
            catch (CouldNotResolvePath)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new CouldNotResolvePath(e);
            }
        }

        public void Update(string Path, object Value)
        {
            try
            {
                Update(PathParser.Parse(Path), Value);
            }
            catch (PathParser.ParseException e)
            {
                throw new CouldNotResolvePath(e);
            }
        }

        private void Update(IEnumerable<IPathNode> Path, object Value)
        {
            object Cursor = null;

            foreach (var Node in Path.Take(Path.Count() - 1))
                Cursor = Node.Resolve(Context, Cursor);

            Path.Last().Update(Context, Cursor, Value);
        }
    }
}